<template>
  <div class="gesture-grid">
    <div ref="gridContainerRef" class="grid-container">
      <canvas ref="canvasRef" class="gesture-canvas" />
      <div
        v-for="point in 9"
        :key="point"
        :class="['grid-point', { active: selectedPoints.includes(point) }]"
        @mousedown="startDrawing(point)"
        @mouseenter="continueDrawing(point)"
      >
        <div class="point-inner">
          <span class="point-number">{{ point }}</span>
        </div>
      </div>
    </div>
    <div class="gesture-sequence">
      <span class="sequence-label">手势序列：</span>
      <span class="sequence-numbers">{{ selectedPoints.join(' → ') || '未绘制' }}</span>
    </div>
    <div class="gesture-actions">
      <a-button type="primary" @click="handleSave">保存</a-button>
      <a-button @click="handleReset">重置</a-button>
    </div>
  </div>
</template>

<script lang="ts" setup>
  import { ref, onMounted, onUnmounted, nextTick } from 'vue';

  const props = defineProps<{
    value?: string;
  }>();

  const emit = defineEmits<{
    (e: 'update:value', value: string): void;
    (e: 'save', value: string): void;
  }>();

  const isDrawing = ref(false);
  const selectedPoints = ref<number[]>([]);
  const gridContainerRef = ref<HTMLDivElement>();
  const canvasRef = ref<HTMLCanvasElement>();
  const pointPositions = ref<{ x: number; y: number }[]>([]);

  const initCanvas = async () => {
    await nextTick();
    const canvas = canvasRef.value;
    const container = gridContainerRef.value;
    if (!canvas || !container) return;

    canvas.width = container.clientWidth;
    canvas.height = container.clientHeight;

    // 计算9个点的位置
    const gridPoints = container.querySelectorAll('.grid-point');
    pointPositions.value = Array.from(gridPoints).map((point) => {
      const rect = point.getBoundingClientRect();
      const containerRect = container.getBoundingClientRect();
      return {
        x: rect.left - containerRect.left + rect.width / 2,
        y: rect.top - containerRect.top + rect.height / 2,
      };
    });
  };

  const drawLines = () => {
    const canvas = canvasRef.value;
    const ctx = canvas?.getContext('2d');
    if (!canvas || !ctx) return;

    ctx.clearRect(0, 0, canvas.width, canvas.height);
    if (selectedPoints.value.length < 2) return;

    ctx.beginPath();
    ctx.strokeStyle = '#1890ff';
    ctx.lineWidth = 2;

    selectedPoints.value.forEach((point, index) => {
      const pos = pointPositions.value[point - 1];
      if (index === 0) {
        ctx.moveTo(pos.x, pos.y);
      } else {
        ctx.lineTo(pos.x, pos.y);
      }
    });
    ctx.stroke();
  };

  const startDrawing = (point: number) => {
    isDrawing.value = true;
    selectedPoints.value = [point];
    drawLines();
  };

  const continueDrawing = (point: number) => {
    if (isDrawing.value && !selectedPoints.value.includes(point)) {
      selectedPoints.value.push(point);
      drawLines();
    }
  };

  const handleSave = () => {
    const gesture = selectedPoints.value.join('');
    emit('save', gesture);
  };

  const handleReset = () => {
    selectedPoints.value = [];
    const canvas = canvasRef.value;
    const ctx = canvas?.getContext('2d');
    if (canvas && ctx) {
      ctx.clearRect(0, 0, canvas.width, canvas.height);
    }
  };

  // 监听全局鼠标事件
  const stopDrawing = () => {
    isDrawing.value = false;
  };

  onMounted(() => {
    document.addEventListener('mouseup', stopDrawing);
    initCanvas();
    window.addEventListener('resize', initCanvas);
  });

  onUnmounted(() => {
    document.removeEventListener('mouseup', stopDrawing);
    window.removeEventListener('resize', initCanvas);
  });
</script>

<style lang="less" scoped>
  .gesture-grid {
    padding: 20px;

    .grid-container {
      display: grid;
      position: relative;
      grid-template-columns: repeat(3, 1fr);
      width: 300px;
      height: 300px;
      margin: 0 auto;
      padding: 20px;
      border-radius: 8px;
      background-color: #f5f5f5;
      gap: 20px;
      user-select: none;

      .gesture-canvas {
        position: absolute;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        pointer-events: none;
      }
    }

    .grid-point {
      display: flex;
      align-items: center;
      justify-content: center;
      cursor: pointer;

      .point-inner {
        display: flex;
        position: relative;
        align-items: center;
        justify-content: center;
        width: 32px;
        height: 32px;
        transition: all 0.3s;
        border-radius: 50%;
        background-color: #d9d9d9;
        pointer-events: none;

        .point-number {
          color: #666;
          font-size: 14px;
          font-weight: 500;
        }
      }

      &.active .point-inner {
        transform: scale(1.2);
        background-color: #1890ff;
      }
    }

    .gesture-sequence {
      margin-top: 16px;
      text-align: center;

      .sequence-label {
        margin-right: 8px;
        color: #666;
      }

      .sequence-numbers {
        color: #1890ff;
        font-size: 16px;
        font-weight: 500;
      }
    }

    .gesture-actions {
      display: flex;
      justify-content: center;
      gap: 16px;
      margin-top: 16px;
    }
  }
</style>
